package com.authine.cloudpivot.ext.applicationservice;


import com.alibaba.cola.dto.SingleResponse;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.authine.cloudpivot.ext.Enum.BillType;
import com.authine.cloudpivot.ext.Enum.TradeOrderType;
import com.authine.cloudpivot.ext.constants.ModelConst;
import com.authine.cloudpivot.ext.dto.FinanceReportDto;
import com.authine.cloudpivot.ext.dto.GatewayResponse;
import com.authine.cloudpivot.ext.dto.Summary;
import com.authine.cloudpivot.ext.dto.model.bill.Bill;
import com.authine.cloudpivot.ext.dto.model.bill.BillReceipt;
import com.authine.cloudpivot.ext.dto.model.bill.OrderToBill;
import com.authine.cloudpivot.ext.dto.model.trade.Trade;
import com.authine.cloudpivot.ext.service.bill.BillService;
import com.authine.cloudpivot.ext.service.bill.impl.BillServiceImpl;
import com.authine.cloudpivot.ext.utils.JdbcTemplateUtils;
import com.authine.cloudpivot.ext.utils.system.ReportUtils;
import com.authine.common.util.DateUtils;
import com.authine.hermes.app.launcher.service.ApplicationService;
import com.authine.mvp.app.launcher.dto.bo.response.BOList;
import io.swagger.v3.oas.annotations.Operation;
import lombok.extern.slf4j.Slf4j;
import org.springframework.util.Assert;

import javax.ws.rs.POST;
import javax.ws.rs.Path;

import java.math.BigDecimal;
import java.util.*;
import java.util.stream.Collectors;

import static com.authine.hermes.app.launcher.service.ApplicationServiceFoundation.CUSTOM_SERVICE;

@Slf4j
@Path("BillController")
public class BillController extends ApplicationService {
    public static BillService billService = new BillServiceImpl();

    /**
     * 确认收货生成商品账单
     * bill只需 type，direction，orderGoodsId,quantity,businessType,referenceId字段
     * 订单模块调用
     * @return
     */
    @Path("createBill")
    @POST
    @Operation(summary = "确认收货生成商品账单",description = "",tags = CUSTOM_SERVICE)
    public SingleResponse createBill(BillReceipt billReceipt){
        try{
            List<String> types = billReceipt.getBills().stream().map(t->t.getType()).distinct().collect(Collectors.toList());
            Assert.isTrue(types.size()==1 && types.get(0).equals(BillType.Goods.name()), "账单类型必须是商品账单");
            for (OrderToBill bill : billReceipt.getBills()){
                Assert.notNull(bill.getOrder_goods_id(), "创建账单失败：订单商品编号不能为空");
                Assert.notNull(bill.getDirection(), "创建账单失败：交易方向不能为空");
                Assert.notNull(bill.getBusiness_type(), "创建账单失败：交易业务类型不能为空");
                Assert.notNull(bill.getQuantity(), "创建账单失败：数量不能为空");
                Assert.notNull(bill.getType(), "创建账单失败：账单类型不能为空");
                Assert.isTrue(bill.getQuantity().compareTo(BigDecimal.ZERO) == 1, "创建账单失败：数量必须大于0");
            }
            billService.createGoodsBill(billReceipt.getBills());
            return SingleResponse.buildSuccess();
        }catch (Exception e){
            log.error("确认收货创建账单异常", JSON.toJSONString(billReceipt),e);
            //todo 回滚订单收货操作
            if(e instanceof  IllegalArgumentException) {
                return SingleResponse.buildFailure("-1",e.getMessage());
            }else{
                return SingleResponse.buildFailure("-1","创建商品账单异常");
            }
        }
    }

    /**
     * 创建退货账单
     * 1、审批退款，退款不退货 bill只需 direction，orderGoodsId,quantity，refundNonExist(true)字段
     * 2、
     * 订单模块调用
     * @return
     */
    @Path("refundBill")
    @POST
    @Operation(summary = "确认退货生成退货账单",description = "",tags = CUSTOM_SERVICE)
    public SingleResponse refundBill(List<Bill> bills){
        if (bills.size() > 50) {
            log.warn("一次退货商品条目不可大于50条参数{}", bills);
            return SingleResponse.buildFailure("-1","一次退货商品条目不可大于50条");
        }
        bills.forEach(t -> t.setType(BillType.Refund.name()));
        try {
            for (Bill param : bills) {
                Assert.notNull(param.getOrder_goods_id(), "创建账单失败：订单商品编号不能为空");
                Assert.notNull(param.getQuantity(), "创建账单失败：数量不能为空");
                Assert.notNull(param.getDirection(), "创建账单失败：交易方向不能为空");
                Assert.isTrue(param.getQuantity().compareTo(BigDecimal.ZERO) == 1, "数量必须大于0");
                param.setBusiness_type(TradeOrderType.Ordinary.name());
            }
            billService.createRefundGoodsBill(bills);
        } catch (IllegalArgumentException e) {
            log.error("退货账单创建参数异常",e);
            return SingleResponse.buildFailure("-1",e.getMessage());
        } catch (Exception e) {
            log.error("退货账单创建异常",e);
            return SingleResponse.buildFailure("-1","系统未捕获的异常信息：" + e.getLocalizedMessage());
        }
        return SingleResponse.buildSuccess();
    }

    /**
     * 平台对账管理-客户对账列表-导出
     * @param query
     * @return
     */
    @Path("exportBill")
    @POST
    @Operation(summary = "平台对账管理-导出查询结果",description = "平台对账管理-客户对账列表-导出,平台对账管理-供应商对账列表-导出",tags = CUSTOM_SERVICE)
    public SingleResponse exportBill(FinanceReportDto query){
        //验证选择导出的报表类型是否正确
        Assert.notNull(query.getReportType().getId(), "导出报表类型异常");
        Assert.notNull(query.getReportName(), "reportName不能为空");

        query.getFilterObj().setPageSize(500);
        SingleResponse<BOList> listBO = listBO(query.getFilterObj());
        List<Map<String, Object>> result = listBO.getData().getData();

        //账单业务要唯一
        List<String> direction = result.stream().map(t->t.get("direction").toString()).distinct().collect(Collectors.toList());
        Assert.isTrue(direction.size()==1, "导出账单方向不唯一");

        //账单对应交易
        List<Trade> tradeList = JdbcTemplateUtils.builder(ModelConst.T_TRADE).selectField("*")
                .in("id", result.stream().map(t->t.get("trade_id")).collect(Collectors.toList()))
                .queryForPOJOList(Trade.class);
        //导出数据
        List<Map<String, Object>> fileData = result.stream().map(item -> {
            Map<String, Object> data = new HashMap<>();
            //交易信息
            Trade trade = tradeList.stream().filter(t->t.getId().equals(item.get("trade_id"))).findFirst().get();
            JSONObject tradeObj = new JSONObject();
            tradeObj.put("erpPo", trade.getErp_po());
            tradeObj.put("time", trade.getCreatedTime());
            tradeObj.put("memberName", trade.getMember_name());
            data.put("trade", tradeObj);
            //账单信息
            data.put("id", item.get("id"));
            data.put("time", item.get("createdTime"));//账单创建时间
            data.put("organizationName", item.get("organization_name"));
            data.put("customerOrderId", item.get("customer_order_id"));
            data.put("vendorOrderId", item.get("customer_order_id"));
            data.put("total", item.get("total"));
            data.put("price", item.get("price"));
            data.put("orderGoodsId", item.get("order_goods_id"));
            data.put("taxRate", item.get("tax_rate"));
            data.put("quantity", item.get("quantity"));
            data.put("type", Enum.valueOf(BillType.class, item.get("type").toString()).des);
            //商品信息
            Summary summary = Summary.conversion(item.get("summary").toString());
            data.put("summaryObject", summary);
            return data;
        }).collect(Collectors.toList());
        ReportUtils.exportReport(query.getReportName(), query.getReportType().getId(), fileData);
        return SingleResponse.buildSuccess();
    }


}
